import json
import random
import time
import uuid
import string
from urllib import parse
import re
print("xxx")
import requests


class XhsApi:

    USER_AGENT = 'Dalvik/2.1.0 (Linux; U; Android 5.1.1; 2014813 MIUI/7.11.16) Resolution/720*1280 Version/6.93.0 Build/6930175 Device/(Xiaomi;2014813) discover/6.93.0 NetType/WiFi'

    COMMON_DEVICE_PARAMS = {
        'platform': 'android',
        'lang': 'zh-Hans',
        'channel': 'YingYongBao',
        'build': '6930175',
        'lang': 'zh-Hans',
        'versionName': '6.93.0',
        'project_id': 'ECFAAF',
        'app_id': 'ECFAAF01',
        'tz': 'Asia/Shanghai',
        'uis': 'light',
        'identifier_flag': '2'
    }

    HOST = 'http://47.105.95.219:8080/'

    URL_BASE = HOST + 'xhsapi/'

    def __init__(self, cid):
        self.__cid = cid
        self.__device_id = ''
        self.__imei = ''
        self.__sid = ''
        self.__smid = ''
        self.__adid = ''
        self.__fid = ''
        self.__mac = ''
        self.__cookie = {}
        self.__bssid = ''
        self.__serial = ''
        self.__cookie = {}

    # 获取注册用户数据
    def get_register_user_data(self):
        return {
            'device_id': self.__device_id,
            'smid': self.__smid,
            'sid': self.__sid,
            'fid': self.__fid,
        }

    def init_new_device_params(self):
        """初始化新设备参数
        :return:
        """
        self.__imei = '26866' + self.__get_random(10)
        self.__adid = '9664' + str(uuid.uuid4())[-12:]
        self.__device_id = str(uuid.uuid4()) # '82d4ee6c-3b15-35a2-908e-6041c9cad78a'
        self.__mac = self.__get_random_mac()
        self.__bssid = self.__get_random_mac()
        self.__serial = '7e' + str(uuid.uuid4())[-10:]
        self.__smid = self.gen_smid()

    # 写入注册用户数据
    def set_register_user_data(self, user_data):
        self.__device_id = user_data['device_id']
        self.__smid = user_data['smid']
        self.__sid = user_data['sid']
        self.__fid = user_data['fid']
        # self.__crypt_method = user_data['crypt_method']


    def init_old_device_params(self, smid, imei, adid, device_id, mac, bssid, serial):
        """初始化已经注册过的设备参数
        :param smid:
        :param imei:
        :param adid:
        :param device_id:
        :param mac:
        :param bssid:
        :param serial:
        :return:
        """
        self.__smid = smid
        self.__imei = imei
        self.__adid = adid
        self.__device_id = device_id
        self.__mac = mac
        self.__bssid = bssid
        self.__serial = serial

    def get_api_access_info(self):
        """获取接口使用情况
        :return:
        """
        querys = {
            'cid': self.__cid,
            'api': 'xiaohongshu'
        }

        response = requests.get(XhsApi.HOST + "info/getApiAccessInfo?" + parse.urlencode(querys))
        return response.text

    def register_smid(self):
        """注册设备
        :return:
        """
        self.__fid = self.get_fid(self.__adid)
        wifi_ip = '192.168.1.1' + self.__get_random(2)

        print('imei: ' + self.__imei)
        print('adid: ' + self.__adid)
        print('device_id: ' + self.__device_id)
        print('mac: ' + self.__mac)
        print('bssid: ' + self.__bssid)
        print('serial: ' + self.__serial)

        api_url = self.URL_BASE + "getDeviceRegisterInfoV2?cid=" + self.__cid
        form_params = {
            'bssid': self.__bssid,
            'imei': self.__imei,
            'serialno': self.__serial,
            'adid': self.__adid,
            'mac': self.__mac,
            'wifiIp': wifi_ip,
            'deviceId': self.__device_id,
            'smid': self.__smid
        }

        print(str(form_params))

        register_info = requests.post(api_url, data=form_params).text
        print(register_info)
        reg_url = 'http://fp-it.fengkongcloud.com/v3/profile/android'
        headers = {
            'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 5.1.1; Redmi 2A MIUI/V9.6.2.0.NCKCNFD)'
        }
        return requests.post(reg_url, data=register_info, headers=headers).text

    def set_smid(self, smid):
        """初始化设备参数
        :return:
        """
        self.__smid = smid
        print('cloudconf:' + self.__init_cloudconf())
        print('app_launch:' + self.__app_launch())

    def get_message(self, blogger_id):
        xhs_url = 'https://www.xiaohongshu.com/api/im/messages/history'
        query_params = {
            'limit': 20,
            'chat_user_id': blogger_id,
            'last_id': 0,
            'start_id': 0,
        }
        return self.__http_get(xhs_url, query_params)

    def get_home_feed(self, oid="homefeed_recommend"):
        """获取首页推荐
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v6/homefeed'
        query_params = {
            'oid': oid,
            # 'cursor_score': '',
            # 'trace_id': str(uuid.uuid4()),
            # 'note_index': '0',
            # 'refresh_type': '1'
        }
        return self.__http_get(xhs_url, query_params)

    def set_user_info_age(self):
        xhs_url = "https://edith.xiaohongshu.com/api/sns/v2/user/info"
        form_params = {
            'key': "age",
            'value': random.randint(18, 35),
        }
        return self.__http_post(xhs_url, form_params, True)

    def set_user_info_gender(self):
        xhs_url = "https://edith.xiaohongshu.com/api/sns/v2/user/info"
        form_params = {
            'key': "gender",
            'value': '1',
        }
        return self.__http_post(xhs_url, form_params, True)

    def set_tag_follow(self):
        xhs_url = "https://www.xiaohongshu.com/api/sns/v2/tag/follow"
        form_params = {
            'data': "%5B%7B%22id%22%3A%225969d60e8022cc5c65bd62ac%22%2C%22type%22%3A%22topic%22%7D%2C%7B%22id%22%3A%225969d60e8022cc5c65bd62b0%22%2C%22type%22%3A%22topic%22%7D%2C%7B%22id%22%3A%225969d60e8022cc5c65bd62ab%22%2C%22type%22%3A%22topic%22%7D%2C%7B%22id%22%3A%225969d60e8022cc5c65bd62ae%22%2C%22type%22%3A%22topic%22%7D%5D"
        }
        return self.__http_post(xhs_url, form_params)

    def recommend_user_social(self):
        xhs_url = "https://www.xiaohongshu.com/api/sns/v1/recommend/user/social?type=weibo"
        query_params = {
            'type': 'weibo',
        }
        return self.__http_get(xhs_url, query_params)


    def get_user_info(self, user_id):
        """获取用户信息
        :param user_id: user id
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v3/user/' + user_id + '/info?'
        return self.__http_get(xhs_url)

    def get_user_note(self, user_id, page, page_size):
        """获取用户笔记
        :param user_id: user id
        :param page: 页码
        :param page_size: 每次返回的条数
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v3/note/user/' + user_id
        query_params = {
            'page': str(page),
            'page_size': str(page_size),
            'sub_tag_id': ''
        }
        return self.__http_get(xhs_url, query_params)

    def get_note_comments(self, note_id, num, start=''):
        """获取note评论
        :param note_id: note id
        :param num: 每次返回的条数
        :param start: 评论id，首页不传，下一页传上一页最后一个评论id
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v5/note/' + note_id + '/comment/list?'
        query_params = {
            'start': start,
            'num': str(num),
            'show_priority_sub_comments': '0',
        }
        return self.__http_get(xhs_url, query_params)

    def get_user_videos(self, user_id, page, page_size):
        """获取用户视频
        :param user_id: user id
        :param page: 页码
        :param page_size: 每次返回的条数
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v3/note/user/' + user_id
        query_params = {
            'page': str(page),
            'page_size': str(page_size),
            'sub_tag_id': 'special.video'
        }
        return self.__http_get(xhs_url, query_params)

    def get_user_followings(self, user_id, start=''):
        """获取用户关注的用户列表
        :param user_id: user id
        :param start: 关注列表中的用户id，首页不传，下一页传上一页最后一个用户id
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/user/' + user_id + '/followings?'
        query_params = {
            'start': start
        }
        return self.__http_get(xhs_url, query_params)

    def get_user_followers(self, user_id, start=''):
        """获取用户粉丝
        :param user_id: user id
        :param start: 粉丝列表中的用户id，首页不传，下一页传上一页最后一个用户id
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/user/' + user_id + '/followers?'
        query_params = {
            'start': start
        }
        return self.__http_get(xhs_url, query_params)

    def search(self, keyword, page, page_size):
        """搜索
        :param keyword: 关键词
        :param page: 页码，最小1
        :param page_size: 每次返回的条数
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v10/search/notes?'
        query_params = {
            'keyword': keyword,
            'filters': '',
            'sort': '',
            'page': str(page),
            'page_size': str(page_size),
            'source': 'explore_feed',
            'search_id': '',
            'api_extra': '',
            'page_pos': str(page_size * (page - 1)),
            'allow_rewrite': '1',
            'geo': '',
            'word_request_id': ''
        }
        return self.__http_get(xhs_url, query_params)

    def get_topic_notes(self, topic_id, page, page_size):
        """获取话题相关的日记
        :param topic_id: 话题id
        :param page: 页码
        :param page_size: 每次返回的条数
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/fe_api/burdock/v1/page/' + topic_id + "/notes?"
        query_params = {
            'page': str(page),
            'pageSize': str(page_size),
            'sid': self.__sid
        }
        return self.__http_get_xsign(xhs_url, query_params)

    def get_video_detail(self, user_id, note_id):
        """获取视频笔记详情
        :param user_id: 用户id
        :param note_id: note id
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/note/user/' + user_id + '/videofeed'
        query_params = {
            'source_note_id': str(note_id),
            'cursor_score': '',
            'num': '5',
            'source': 'posted'
        }
        return self.__http_get(xhs_url, query_params)

    def get_note_detail(self, note_id):
        """获取笔记详情
        :param note_id:
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/note/feed'
        query_params = {
            'note_id_list': str(note_id),
            'source_note_id': str(note_id)
        }
        return self.__http_get(xhs_url, query_params)

    def send_sms_code(self, phone_number, zone='86'):
        """发送短信验证码
        :param phone_number: 手机号码
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/system_service/vfc_code?'
        query_params = {
            'zone': zone,
            'phone': str(phone_number),
            'type': 'login'
        }
        return self.__http_get(xhs_url, query_params)

    def check_sms_code(self, phone_number, code, zone='86'):
        """校验短信验证码
        :param phone_number: 手机号码
        :param code: 验证码
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/system_service/check_code?'
        query_params = {
            'zone': zone,
            'phone': str(phone_number),
            'code': str(code),
        }
        return self.__http_get(xhs_url, query_params)

    def login_with_sms(self, phone_number, mobile_token):
        """ 短信验证码登录
        :param phone_number: 手机号码
        :param mobile_token: token，由check_sms_code返回
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v4/user/login/code'
        form_params = {
            'phone': str(phone_number),
            'imei': self.__imei,
            'imei_encrypted': self.encrypt_imei(self.__imei, self.__device_id),
            'zone': '86',
            'type': 'phone',
            'mobile_token': mobile_token,
            'android_id': self.__adid,
            'mac': self.__mac
        }

        ret = self.__http_post(xhs_url, form_params)
        print('login_with_sms:' + ret)
        success = json.loads(ret)['success']
        if success:
            return json.loads(ret)['data']
        return ''

    def login_with_weibo_h5(self, username, password):
        """微博登录
        :param username: 用户名
        :param password: 密码
        :return:
        """
        # 先登录微博
        login_form_params = {
            'username': str(username),
            'password': str(password),
            'savestate': '1',
            'r': '',
            'ec': '0',
            'pagerefer': '',
            'entry': 'mweibo',
            'wentry': '',
            'rf': '1',
            'loginfrom': '2',
            'client_id': '608714079',
            'code': '',
            'qq': '',
            'mainpageflag': '1',
            'hff': '',
            'hfp': ''
        }

        headers = {
            'User-Agent': 'Xiaomi-2014813_5.1.1_weibosdk_0041005000_android',
            'Referer': 'https://passport.weibo.cn/signin/login?client_id=608714079&redirect_uri=http://www.xiaohongshu.com/&display=sdk&action=login&rf=1&version=0041005000&sso_type=1&offcialMobile=true&scope=all'
        }

        weibo_login_url = 'https://passport.weibo.cn/sso/login'
        login_resp = requests.post(weibo_login_url, data=login_form_params, headers=headers).json()
        print(str(login_resp))
        retcode = login_resp['retcode']
        if retcode != 20000000:
            print('weibo login failed')
            return ''

        data = login_resp['data']
        ticket = data['ticket']
        uid = data['uid']
        print('ticket:' + ticket + ', uid:' + uid)

        # 授权
        auth_form_params = {
            'client_id': '608714079',
            'redirect_uri': 'http://www.xiaohongshu.com/',
            'display': 'sdk',
            'action': 'login',
            'rf': '1',
            'version': '0041005000',
            'sso_type': '1',
            'offcialMobile': 'true',
            'scope': 'all',
            'wm': '3349',
            'ticket': ticket
        }

        auth_url = 'https://open.weibo.cn/oauth2/authorize'
        auth_resp = requests.post(auth_url, data=auth_form_params, headers=headers, allow_redirects=False)
        status_code = auth_resp.status_code
        print('auth status code:' + str(status_code))
        # 已经授权过
        if status_code == 302:
            redirect_url = auth_resp.headers['Location']
            print('auth redirect_url:' + redirect_url)
        else:
            # 未授权过
            match = re.search('^\s*<input type="hidden" name="verifyToken" value="(\S+)"/>', auth_resp.text, re.M)
            if match:
                verify_token = match.group(1)
                print('verify_token:' + verify_token)

                auth_form_params = {
                    'display': 'sdk',
                    'action': 'scope',
                    'scope': 'follow_app_official_microblog',
                    'withOfficalFlag': '0',
                    'withOfficalAccount': 'null',
                    'response_type': 'code',
                    'regCallback': 'https%3A%2F%2Fopen.weibo.cn%2F2%2Foauth2%2Fauthorize%3Fclient_id%3D608714079%26response_type%3Dcode%26display%3Dsdk%26redirect_uri%3Dhttp%253A%252F%252Fwww.xiaohongshu.com%252F%26from%3D%26with_cookie%3D',
                    'redirect_uri': 'http://www.xiaohongshu.com/',
                    'client_id': '608714079',
                    'appkey62': 'YAyVF',
                    'state': '',
                    'from': '',
                    'offcialMobile': 'true',
                    'uid': str(uid),
                    'url': '',
                    'verifyToken': verify_token,
                    'visible': '0',
                    'version': '0041005000',
                    'sso_type': '1',
                }

                auth_resp = requests.post(auth_url, data=auth_form_params, headers=headers, allow_redirects=False)
                print(auth_resp.text)
                status_code = auth_resp.status_code
                print('auth status code:' + str(status_code))
                if status_code == 302:
                    redirect_url = auth_resp.headers['Location']
                    print('auth redirect_url:' + redirect_url)
                else:
                    print('weibo auth failed')
                    return ''
            else:
                print('get verify_token failed')
                return ''

        # 获取微博用户信息
        access_token = parse.parse_qs(parse.urlparse(redirect_url).query)['access_token'][0]
        print('access_token:' + access_token)
        user_query_params = {
            'uid': str(uid),
            'access_token': access_token,
            'aid': '01A7CmmK0Lg-qh78sau7BGF07Ki0pYXBO07S65phgkwCBvapw.',
            'oauth_timestamp': str(round(time.time())),
            'oauth_sign': '27670ad'
        }

        userinfo_url = 'https://api.weibo.com/2/users/show.json?' + parse.urlencode(user_query_params)
        user_info = requests.get(userinfo_url).json()
        print('user_info:' + str(user_info))

        # 小红书登录
        avatar = user_info['avatar_hd']
        location = user_info['location']
        nickname = user_info['name']
        print('avatar:' + avatar + ', location:' + location + ', nickname:' + nickname)
        login_form_params = {
            'imageb': avatar,
            'images': avatar,
            'imei': self.__imei,
            'imei_encrypted': self.encrypt_imei(self.__imei, self.__device_id),
            'location': location,
            'nickname': nickname,
            'token': access_token,
            'verifyReason': 'none',
            'gender': '0',
            'verifyType': '-1',
            'type': 'weibo',
            'tokenExireTime': '1970-01-01 08:00:00',
            'openid': str(uid),
            'mac': self.__mac
        }

        login_url = 'https://www.xiaohongshu.com/api/sns/v4/user/login/social'
        ret = self.__http_post(login_url, login_form_params)
        print('login_with_weibo:' + ret)
        success = json.loads(ret)['success']
        if success and 'data' in json.loads(ret):
            return json.loads(ret)['data']['session']
        return ''

    def login_with_weibo_app(self, username, password, cptcode=None):
        """微博app授权登录
        :param username: 微博账号
        :param password: 微博密码
        :param cptcode: 验证码
        :return:
        """
        # 微博登录
        query_params = {
            'u': username,
            'p': self.encrypt_weibo_passwd(password),
            'android_id': self.__adid,
            'imei': self.__imei,
            'guestid': '',
            's': self.calculate_weibo_sign(username + password),
        }

        if cptcode is not None:
            query_params['cptcode'] = cptcode

        form_params = {
            'device_name': 'Xiaomi-2014813',
            'firstLogin': '1',
            'getuser': '1',
            'getcookie': '1',
            'getoauth': '1'
        }

        headers = {
            'User-Agent': '2014813_5.1.1_weibo_10.8.1_android'
        }

        url = 'https://api.weibo.cn/2/account/login?networktype=wifi&launchid=10000365--x&sensors_device_id=&uicode=10000762&moduleID=701&checktoken=9834b142321af9ef047a89766f7ade78&wb_version=4576&preload_ab=1&c=android&ft=0&ua=Xiaomi-2014813__weibo__10.8.1__android__android5.1.1&wm=2468_1001&aid=&did=&v_f=2&v_p=85&flag=1&from=10A8195010&lang=zh_CN&skin=default&device_id=&request_ab=1&oldwm=2468_1001&sflag=1&guestid=&sensors_mark=0&sensors_is_first_day=true&launchid_4580=10000365--x&cum=69B70F24'
        resp = requests.post(self.__append_url_params(url, query_params), data=form_params, headers=headers).json()
        # print(json.dumps(resp))
        if 'errno' in resp:
            print('login_with_weibo_app error: ' + resp['errmsg'])
            return ''

        access_token = resp['oauth2.0']['access_token']
        print('access_token:' + access_token)

        uid = resp['uid']
        gsid = resp['gsid']
        print('uid:' + uid)
        print('gsid:' + gsid)

        # 授权获取access_token
        form_params = {
            'access_token': access_token,
            'client_id': '608714079',
            'aid': '',
            'scope': 'all',
            'key_hash': '',
            'packagename': 'com.xingin.xhs',
            'redirect_uri': 'http://www.xiaohongshu.com/',
            'display': 'mobile',
            'quick_auth': 'false'
        }

        url = 'https://api.weibo.com/oauth2/sso_authorize?launchid=10000360-com.xingin.xhs-x&lang=zh_CN&sflag=1&launchid_4580=10000360-com.xingin.xhs-x'
        resp = requests.post(url, data=form_params, headers=headers).text
        # print(resp)

        form_params['action'] = 'submit'
        form_params['scope'] = 'follow_app_official_microblog'
        resp = requests.post(url, data=form_params, headers=headers).json()
        # print(json.dumps(resp))
        access_token = resp['access_token']
        print('access_token:' + access_token)

        # 微博用户信息
        query_params = {
            'android_id': self.__adid,
            'imei': self.__imei,
            'guestid': '',
            's': self.calculate_weibo_sign(uid),
            'gsid': gsid
        }

        form_params = {
            'device_name': 'Xiaomi-2014813',
            'firstLogin': '1',
            'getuser': '1',
            'getcookie': '1',
            'getoauth': '1'
        }

        url = 'https://api.weibo.cn/2/account/login?networktype=wifi&launchid=10000360-com.xingin.xhs-x&sensors_device_id=none&moduleID=701&wb_version=4576&preload_ab=1&c=android&ft=0&ua=Xiaomi-2014813__weibo__10.8.1__android__android5.1.1&wm=2468_1001&aid=&v_f=2&v_p=85&from=10A8195010&lang=zh_CN&skin=default&device_id=&request_ab=1&oldwm=2468_1001&sflag=1&sensors_mark=0&sensors_is_first_day=none&launchid_4580=10000360-com.xingin.xhs-x&cum=3267C673'
        resp = requests.post(self.__append_url_params(url, query_params), data=form_params, headers=headers).json()
        # print(json.dumps(resp))

        # 小红书登录
        login_form_params = {
            'imei': '',
            'imei_encrypted': self.encrypt_imei(self.__imei, self.__device_id),
            'token': access_token,
            'type': 'weibo',
            'openid': str(uid),
            'mac': self.__mac
        }

        login_url = 'https://www.xiaohongshu.com/api/sns/v5/user/login/social'
        ret = self.__http_post(login_url, login_form_params)
        print('login_with_weibo_app:' + ret)
        success = json.loads(ret)['success']
        if success and 'data' in json.loads(ret):
            return json.loads(ret)['data']['session']
        return ''

    def refresh_session(self):
        """更新session
        :return: 新session
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v3/user/me'
        ret = self.__http_get(xhs_url)
        return json.loads(ret)['data']['session']

    def get_login_userinfo(self):
        """获取登录用户信息
        :return:
        """
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v3/user/me'
        return self.__http_get(xhs_url)

    def set_session_id(self, session_id):
        """设置session id
        :param session_id: session id
        :return:
        """
        if len(session_id) > 0:
            if session_id.startswith('session.'):
                self.__sid = session_id
            else:
                self.__sid = 'session.' + session_id

    def get_session_id(self):
        """获取session id
        :return:
        """
        return self.__sid

    def active_user(self):
        """激活用户，获取sid
        :return:
        """
        xhs_url = 'https://edith.xiaohongshu.com/api/sns/v1/user/activate'
        encrpted_imei = self.encrypt_imei(self.__imei, self.__device_id)
        form_params = {
            'idfa': '',
            'idfv': '',
            'android_id': self.__adid,
            'channel': '',
            'pasteboard': '',
            'category': '',
            'oaid': '',
            'android_version': '22',
            'mac': self.__mac,
            'gaid': '',
            'attribution_id': '{"imei0": "' + encrpted_imei + '","imei1":"' + encrpted_imei + '"}',
            'imei_encrypted': encrpted_imei,
        }

        return self.__http_post(xhs_url, form_params)

    def encrypt_dev_info(self, register_info):
        """加密设备注册信息
        :param register_info:
        :return:
        """
        api_url = self.URL_BASE + "encryptDevInfo?cid=" + self.__cid
        return requests.post(api_url, data=register_info).text

    def get_fid(self, aid):
        """获取fid
        :param aid: android id
        :return:
        """
        api_url = self.URL_BASE + "getFid?cid=" + self.__cid + '&aid=' + aid
        resp = requests.get(api_url)
        print(resp.text)
        return resp.json()['fid']

    def gen_smid(self):
        """生成新smid
        :return:
        """
        api_url = self.URL_BASE + "getSmid?cid=" + self.__cid
        resp = requests.get(api_url)
        print(resp.text)
        return resp.json()['smid']

    def encrpyt_password(self, password):
        """加密密码
        :param password:
        :return:
        """
        api_url = self.URL_BASE + 'encryptPassword?cid=' + self.__cid + '&password=' + password
        return requests.get(api_url).json()['password']

    def encrypt_imei(self, imei, device_id):
        """加密imei
        :param imei:
        :param device_id:
        :return:
        """
        query_params = {
            'cid': self.__cid,
            'imei': imei,
            'deviceId': device_id
        }

        api_url = self.URL_BASE + 'encryptImei?' + parse.urlencode(query_params)
        return requests.get(api_url).json()['imei_encrypted']

    def encrypt_weibo_passwd(self, passwd):
        """加密weibo密码
        :param passwd: 密码
        :return:
        """
        query_params = {
            'cid': self.__cid,
            'passwd': passwd
        }

        api_url = self.URL_BASE + 'encryptWeiboPasswd?' + parse.urlencode(query_params)
        return requests.get(api_url).json()['p']

    def calculate_weibo_sign(self, content):
        """计算weibo签名
        :param content: 要签名的内容
        :return:
        """
        query_params = {
            'cid': self.__cid,
            'content': content
        }

        api_url = self.URL_BASE + 'calculateS?' + parse.urlencode(query_params)
        return requests.get(api_url).json()['s']

    def login_with_passwd(self, phone, password):
        """账号密码登录
        :param phone:
        :param password:
        :return:
        """
        form_params = {
            'password': self.encrpyt_password(password),
            'phone': str(phone),
            'imei': '',
            'imei_encrypted': self.encrypt_imei(self.__imei, self.__device_id),
            'zone': '86',
            'type': 'phone',
            'android_id': self.__adid,
            'android_version': '22',
            'mac': self.__mac
        }

        xhs_url = 'https://www.xiaohongshu.com/api/sns/v4/user/login/password'
        return self.__http_post(xhs_url, form_params)

    def __init_cloudconf(self):
        xhs_url = 'http://fp-it.fengkongcloud.com/v3/cloudconf'

        headers = {
            'User-Agent': 'Dalvik/2.1.0 (Linux; U; Android 5.1.1; 2014813 MIUI/7.11.16)'
        }

        infos = {
            "organization": "eR46sBuqF0fdw7KWFLYa",
            "data": {
                "sdkver": "2.8.8",
                "enc": 1,
                "smid": self.__smid,
                "md5": "988751ca8e09f518984ff7b0bc98753a",
                "os": "android",
                'sid': str(round(time.time() * 1000)) + '-' + self.__get_random(5)
            }
        }

        return requests.post(xhs_url, data=str(json.dumps(infos)), headers=headers).text

    def __app_launch(self):
        xhs_url = 'https://www.xiaohongshu.com/api/sns/v1/system_service/launch?'
        query_params = {
            'build': '6340153',
            'package': 'discovery'
        }
        return self.__http_get(xhs_url, query_params)

    def __get_random(self, len):
        return ''.join(str(random.choice(range(10))) for _ in range(len))

    def __get_random_str(self, len):
        return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(len))

    def __get_random_mac(self):
        mac = [0xf6, 0xf5, 0xdb,
               random.randint(0x00, 0x7f),
               random.randint(0x00, 0xff),
               random.randint(0x00, 0xff)]
        return ':'.join(map(lambda x: "%02x" % x, mac))

    def __get_sign_url(self):
        querys = {
            'cid': self.__cid
        }

        sign_url = self.URL_BASE + 'getSignV3?' + parse.urlencode(querys)
        return sign_url

    def __get_xsign_url(self):
        querys = {
            'cid': self.__cid
        }

        sign_url = self.URL_BASE + 'getXSign?' + parse.urlencode(querys)
        return sign_url

    def __http_get_xsign(self, url, query_params={}):
        params = parse.urlencode(query_params)
        if len(query_params) != 0:
            if not url.__contains__('?'):
                url = url + '?'

            if url.endswith('?') or url.endswith('&'):
                url = url + params
            else:
                url = url + '&' + params

        try:
            xsign_url = self.__get_xsign_url()
            form_params = {
                'url': url
            }

            xsign_resp = requests.post(xsign_url, data=form_params).json()
            headers = {
                'User-Agent': self.USER_AGENT,
                'X-Sign': xsign_resp['X-Sign']
            }
            return requests.get(url, headers=headers).text
        except Exception as e:
            print(repr(e))

    def __get_sign(self, params={}):
        # 获取sign和shield
        for i in range(5):
            try:
                sign_resp = requests.post(self.__get_sign_url(), data=params).json()
                print(sign_resp)
                if 'ret' in sign_resp:
                    print(sign_resp)
                    return ""

                if 'shield' not in sign_resp:
                    continue

                shield = sign_resp['shield']
                if len(shield) == 0:
                    continue
                return sign_resp
            except Exception as e:
                print(repr(e))

    def __http_post(self, url, form_params=None, new_user=False):
        if form_params is None:
            form_params = {}

        t = str(round(time.time()))
        sign_params = {
            'xy-common-params': self.__get_xy_common_params(t, new_user),
            'body_params': parse.urlencode(form_params),
            'url': url,
            'deviceId': self.__device_id
        }

        #print(str(sign_params))

        sign = self.__get_sign(sign_params)
        shield = sign['shield']

        # 请求小红书
        headers = self.__get_headers(t, shield, new_user)
        cookies = self.__cookie
        print('url -->', url)
        # print('data -->', form_params)
        # print('headers -->', headers)
        # print('cookies -->', cookies)
        resp = requests.post(url, data=form_params, headers=headers, cookies=cookies)
        self.__cookie = resp.cookies.get_dict()
        return resp.text

    def __http_get(self, url, query_params=None):
        if query_params is None:
            query_params = {}

        t = str(round(time.time()))
        url = self.__append_url_params(url, query_params)
        form_params = {
            'xy-common-params': self.__get_xy_common_params(t),
            'url': url,
            'deviceId': self.__device_id
        }

        sign = self.__get_sign(form_params)
        shield = sign['shield']

        # 请求小红书
        resp = requests.get(url, headers=self.__get_headers(t, shield), cookies=self.__cookie)
        self.__cookie = resp.cookies.get_dict()
        return resp.text

    def __get_common_params(self, t):
        common_params = {
            'deviceId': self.__device_id,
            'device_fingerprint': self.__smid,
            'device_fingerprint1': self.__smid,
            'sid': self.__sid,
            't': str(t),
            'fid': self.__fid,
        }

        common_params.update(self.COMMON_DEVICE_PARAMS)
        return common_params

    def __get_xy_common_params(self, t, new_user=False):
        xy_common_params = {}
        if new_user:
            xy_common_params = {
                'x_trace_page_current': 'new_user_profile_page'
            }
        # print('new_user ==>', new_user)
        # print('xy_common_params ==>', xy_common_params)
        xy_common_params.update(self.__get_common_params(t))
        # print('22222222222222xy_common_params ==>', xy_common_params)
        return parse.urlencode(xy_common_params)

    def __get_xy_platform_info(self):
        return 'platform=android&build=6930175&deviceId=' + self.__device_id

    def __get_headers(self, t, shield, new_user=False):
        headers = {
            'xy-common-params': self.__get_xy_common_params(t, new_user),
            'User-Agent': self.USER_AGENT,
            'shield': shield,
            'xy-platform-info': self.__get_xy_platform_info()
        }

        return headers

    def __append_url_params(self, url, query_params):
        params = parse.urlencode(query_params)
        if not url.__contains__('?'):
            url = url + '?'

        if url.endswith('?') or url.endswith('&'):
            url = url + params
        else:
            url = url + '&' + params
        return url


if __name__ == '__main__':
    xhs_api = XhsApi("16c01b86dbf1af2a")
    device_data = {"device_id": "6d50ffc8-7e0f-35af-917b-8e974e93daa3", "smid": "202108011015418cc4f8ef9f461c82464c4672ef66180c0088e3d56835a200", "device_fingerprint1": "202107101522494b5a757e17110e860d6de86e2c15822f01b42f06e8730b88", "device_fingerprint": "202108011015418cc4f8ef9f461c82464c4672ef66180c0088e3d56835a200", "sid": "session.1627784169755300920882", "fid": "1627784142100f2578c86536d551aa9bd4ffff97b8bd", "register_time": "2021-06-26 23:45:29"}
    xhs_api.set_register_user_data(device_data)
    result = xhs_api.get_home_feed()
    print("result -->", result)
    api_access_info = xhs_api.get_api_access_info()
    print('api_access_info:' + api_access_info)
